// @title WebAPI 文档
// @version 1.0
// @description 网页捕获和邮件发送API
// @host localhost:8080
// @BasePath /

package main

import (
	"context"
	"fmt"
	"log"
	"net/http"

	gomail "gopkg.in/mail.v2"

	"github.com/chromedp/cdproto/cdp"
	"github.com/chromedp/chromedp"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	swaggerFiles "github.com/swaggo/files"     // 导入
	ginSwagger "github.com/swaggo/gin-swagger" // 导入 ginSwagger
)

type SendMailRequest struct {
	// @Description	收件人地址
	To string `json:"to" binding:"required,email"`
	// @Description	邮件主题
	Subject string `json:"subject" binding:"required"`
	// @Description	邮件内容
	Body string `json:"body" binding:"required"`
}

type SendMailResponse struct {
	Message string `json:"message"`
}

type WebCatchRequest struct {
	// @Description	要捕获的网页地址
	Url string `json:"url" binding:"required"`
	// @Description	要捕获的元素css选择器
	Selector string `json:"selector" binding:"required"`
	// @Description	要捕获的元素属性名（默认为text）
	Attr string `json:"attr" binding:"required"`
}

type WebCatchResponse struct {
	Message string   `json:"message"`
	Content []string `json:"content"`
}

func getTextFromNode(node *cdp.Node) string {
	var result string

	// 递归函数
	var traverse func(*cdp.Node)
	traverse = func(n *cdp.Node) {
		// 如果当前节点是 TextNode，将其 Data 拼接到结果中
		if n.NodeType == 3 {
			result += n.NodeValue
		}
		// 遍历当前节点的所有子节点
		for _, c := range n.Children {
			traverse(c)
		}
	}

	// 从根节点开始递归
	traverse(node)
	return result
}

// @Summary		捕获网页
// @Description	指定url和元素的css选择器，以及输出的属性名（以及text和text[])
// @Tags			web
// @Accept			json
// @Produce		json
// @Param		request	body	WebCatchRequest	true	"发送邮件请求"
// @Success		200				{object} WebCatchResponse	"网页捕获成功"
// @Failure		400				{object} WebCatchResponse	"请求参数错误"
// @Failure		500				{object} WebCatchResponse	"内部服务器错误"
// @Router			/api/webcatch [post]
func webCatch(c *gin.Context) {
	var request WebCatchRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, WebCatchResponse{Message: err.Error()})
		log.Fatalln(err)
		return
	}
	ctx, cancel := chromedp.NewContext(
		context.Background(),
	)
	defer cancel()
	var nodes []*cdp.Node
	err := chromedp.Run(ctx,
		chromedp.Navigate(request.Url),
		chromedp.WaitVisible(request.Selector),
		chromedp.Nodes(request.Selector, &nodes),
	)
	if err != nil {
		c.JSON(http.StatusBadRequest, WebCatchResponse{Message: err.Error()})
		log.Fatal(err)
		return
	}
	var texts []string
	if request.Attr == "value" {
		for _, node := range nodes {
			texts = append(texts, node.Value)
		}
	} else if request.Attr == "text" {
		for _, node := range nodes {
			texts = append(texts, getTextFromNode(node))
		}
	} else {
		for _, node := range nodes {
			text, exists := node.Attribute(request.Attr)
			if exists {
				texts = append(texts, text)
			} else {
				texts = append(texts, "")
			}

		}
	}

	c.JSON(http.StatusOK, WebCatchResponse{
		Message: "webCatch successfully",
		Content: texts,
	})

}

// @Summary		发送邮件
// @Description	发送一封邮件给指定的收件人
// @Tags			email
// @Accept			json
// @Produce		json
// @Param			request	body		SendMailRequest		true	"发送邮件请求"
// @Success		200				{object}	SendMailResponse	"邮件发送成功"
// @Failure		400				{object}	SendMailResponse	"请求参数错误"
// @Failure		500				{object}	SendMailResponse	"内部服务器错误"
// @Router			/api/sendmail [post]
func sendMail(c *gin.Context) {
	var request SendMailRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, SendMailResponse{Message: err.Error()})
		return
	}

	// 读取配置文件中的 SMTP 设置
	smtpHost := viper.GetString("smtp.host")
	smtpPort := viper.GetInt("smtp.port")
	smtpUser := viper.GetString("smtp.user")
	smtpPass := viper.GetString("smtp.password")

	// 邮件内容
	m := gomail.NewMessage()
	m.SetHeader("From", smtpUser)
	m.SetHeader("To", request.To)
	m.SetHeader("Subject", request.Subject)
	m.SetBody("text/plain", request.Body)

	d := gomail.NewDialer(smtpHost, smtpPort, smtpUser, smtpPass)

	if err := d.DialAndSend(m); err != nil {
		fmt.Println("Error:", err)
		log.Fatalln(err)
	} else {
		log.Println("Email sent successfully!")
	}

	// err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{to}, msg)
	// if err != nil {
	// 	log.Printf("smtp error: %s", err)
	// 	return
	// }

	c.JSON(http.StatusOK,
		SendMailResponse{Message: "Email sent successfully"})
}

func main() {
	// 初始化 viper 读取配置文件
	viper.SetConfigName("config") // 配置文件名（不带扩展名）
	viper.SetConfigType("yaml")   // 配置文件类型
	viper.AddConfigPath(".")      // 配置文件路径

	if err := viper.ReadInConfig(); err != nil {
		log.Fatalf("Error reading config file, %s", err)
	}

	r := gin.Default()

	// 加载 OpenAPI 规范文件（可选，用于文档生成）
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	r.POST("/api/sendmail", sendMail)
	r.POST("/api/webcatch", webCatch)

	httpHost := viper.GetString("http.host")
	httpPort := viper.GetString("http.port")
	r.Run(httpHost + ":" + httpPort)
}
